#include "flash.h"

/*private define***********************************************************************/

/*private variables***********************************************************************/
static FLASH_EraseInitTypeDef EraseInitStruct;
/*private function prototypes***********************************************************************/

flash_status_t flash_page_write(uint32_t address, uint32_t* data, uint32_t page_number)
{
    uint32_t word_count = 0;
    uint32_t nbofwords = 0, page_error;
    /* Unlock the Flash to enable the flash control register access */ 
    HAL_FLASH_Unlock();
    /* Erase the user Flash area*/
    /* Fill EraseInit structure*/
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = address;
    EraseInitStruct.NbPages = page_number;
   
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &page_error) != HAL_OK)
        return FLASH_ERROR;
    
    /* Get the number of sector to erase from 1st sector*/
    nbofwords = page_number * 4;
    /* Program the user Flash area word by word*/
    for(word_count  = 0; word_count < nbofwords; word_count++)
    {
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, *(data + word_count)) == HAL_OK)
            address += 4;
        else
            return FLASH_ERROR;
    }
    /* Lock the Flash to disable the flash control register access*/
    HAL_FLASH_Lock(); 
     
    return FLASH_OK;
}

flash_status_t flash_sector_write(uint32_t address, uint32_t* data)
{
    uint32_t ret;
 
    ret = flash_page_write(address, data, FLASH_PAGE_NUMBER_OF_SECTOR);
    if(ret != FLASH_OK)
        return FLASH_ERROR;
    
    return FLASH_OK;
}

flash_status_t flash_page_erase(uint32_t address, uint32_t page_number)
{
    uint32_t page_error = 0;
    /* Unlock the Flash to enable the flash control register access */ 
    HAL_FLASH_Unlock();
    /* Erase the user Flash area*/
    /* Fill EraseInit structure*/
    EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = address;
    EraseInitStruct.NbPages = page_number;
   
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &page_error) != HAL_OK)
        return FLASH_ERROR;
    
    return FLASH_OK;
}

flash_status_t flash_page_content_check(uint32_t address, uint32_t* data, uint32_t page_number)
{
    uint32_t memory_program_status = 0;
    uint32_t word_count = 0, nbofwords = 0;
    
    nbofwords = page_number * 4;
    for(word_count = 0; word_count < nbofwords; word_count++)
    {
        if(*(data + word_count) != *(__IO uint32_t*)address)
            memory_program_status++;
        
        address+=4;
    }
    
    if(memory_program_status != 0)
        return FLASH_ERROR;
  
    return FLASH_OK;
}




